package com.open.exam.common;

import com.google.gson.Gson;
import com.open.exam.databasemodel.*;
import com.open.exam.dto.AdminInfo;
import com.open.exam.dto.ExamCount;
import com.open.exam.dto.ExamineeExamPaperItem;
import com.open.exam.enums.ExamManagerState;
import com.open.exam.examinerbehavior.AccidentsProcessRecord;
import com.open.exam.examinerbehavior.ChangeSeatRecord;
import com.open.exam.examinerbehavior.DelayRecord;
import com.open.exam.examinerbehavior.ViolateRuleRecord;
import com.open.exam.examplan.ExamPlan;
import com.open.exam.utils.HttpRequestUtils;
import com.openexam.openqti.openqtipaperquestion.ItemType;
import com.openexam.openqti.qti.CompletionStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

/**
 * @author 奶茶
 * Created on 2017/11/7.
 */
public class CommonFunction {

    private static final Logger logger = LoggerFactory.getLogger(CommonFunction.class.getName());

    /**
     * 响应数据流
     * @param response
     * @param result
     */
    public static void responseWrite(HttpServletResponse response, Object result){
        Gson gson = new Gson();
        try {
            response.setContentType("application/json;charset=UTF-8");
            response.setStatus(HttpStatus.OK.value());
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.getWriter().write(gson.toJson(result));
        } catch (IOException e) {
            logger.error("ResponseException",e);
        }
    }

    public static String replaceNS2(String strXML){
        return strXML.replace("<ns2:","<").replace("</ns2:","</").replace("xmlns:ns2=\"http://www.open.com.cn/schemas/exam/invigilationReport\"","xmlns=\"http://www.open.com.cn/schemas/exam/invigilationReport\"");
    }



    /**
     * *******************************  .net 实现 ********************************
     */
    public static ExamApp examAppsFirstOrDefault(List<ExamApp> examApps, String appId){
        if(!examApps.isEmpty() && appId != null && !("").equals(appId)){
            for (ExamApp examApp:examApps){
                if(examApp.getAppID().equalsIgnoreCase(appId)){
                    return examApp;
                }
            }
        }
        return null;
    }

    public static ExamSite examSitesFirstOrDefault(List<ExamSite> examSites, String examSiteCode){
        if(!examSites.isEmpty() && examSiteCode != null && !("").equals(examSiteCode)){
            for (ExamSite examSite:examSites){
                if(examSite.getExamSiteCode().equalsIgnoreCase(examSiteCode)){
                    return examSite;
                }
            }
        }
        return null;
    }

    public static ExamSite examSitesByIDFirstOrDefault(List<ExamSite> examSites, String examISteID){
        if(!examSites.isEmpty() && examISteID != null && !("").equals(examISteID)){
            for (ExamSite examSite:examSites){
                if(examSite.getExamSiteID().equalsIgnoreCase(examISteID)){
                    return examSite;
                }
            }
        }
        return null;
    }

    public static ExamSite examSitesFirstOrDefault(List<ExamSite> examSites, String examSiteID,String examSitePwd){
        if(!examSites.isEmpty() && examSiteID != null && !examSiteID.equals(0)){
            for (ExamSite examSite:examSites){
                if(examSite.getExamSiteID().equals(examSiteID) && examSite.getSitePwd().equals(examSitePwd)){
                    return examSite;
                }
            }
        }
        return null;
    }

    public static List<ExamCount> examCountsDistinct(List<ExamCount> examCounts){
        List<ExamCount> examCountList = new ArrayList<>();
        if(!examCounts.isEmpty()){
            List<String> examPlanInfoIds = new ArrayList<>();
            for (ExamCount examCount:examCounts){
                if(!examPlanInfoIds.contains(examCount.getExamPlanInfoId())){
                    examPlanInfoIds.add(examCount.getExamPlanInfoId());
                    examCountList.add(examCount);
                }
            }
        }
        return examCountList;
    }

    public static ExamCount examCountsFirstOrDefault(String appId,String examPlanInfoId,List<ExamCount> examCounts){
        if(examCounts != null && !examCounts.isEmpty()){
            for (int i=0;i<examCounts.size();i++){
                if(examCounts.get(i).getExamPlanInfoId().equals(examPlanInfoId)){
                    return examCounts.get(i);
                }
            }
        }
        return null;
    }

    public static ExamScenes examScenesFind(List<ExamScenes> examScenesList, String examSceneId){
        if(!examScenesList.isEmpty()){
            for (ExamScenes examScenes:examScenesList) {
                if(examScenes.getExamSceneID().equals(examSceneId)){
                    return examScenes;
                }
            }
        }
        return null;
    }

    public static ExamSubject examSubjectFind(List<ExamSubject> subjectList,String subjectId){
        if(!subjectList.isEmpty()){
            for (ExamSubject examSubject:subjectList) {
                if(examSubject.getExamSubjectID().equals(subjectId)){
                    return examSubject;
                }
            }
        }
        return null;
    }

    public static ExamineeArrange examineeArrangeFirstOrDefault(List<ExamineeArrange> examineeArrangeList, String appId, String examPlanInfoId, String examineeId){
        if(!examineeArrangeList.isEmpty()){
            for (ExamineeArrange examineeArrange:examineeArrangeList) {
                if(examineeArrange.getAppID().equals(appId) && examineeArrange.getExamPlanInfoID().equals(examPlanInfoId) && examineeArrange.getExamineeID().equals(examineeId)){
                    return examineeArrange;
                }
            }
        }
        return null;
    }

    public static Map<String,Object> maxTimeLimitsAndSubjectName(List<ExamSubject> examSubjects){
        Map<String,Object> map = new HashMap<>();
        if(examSubjects != null && !examSubjects.isEmpty()){
            Integer maxTime = 0;
            //StringBuilder sb = new StringBuilder();
            //for (int i=0;i<examSubjects.size();i++) {
            //    if(examSubjects.get(i).getTimeLimits() > maxTime){
            //        maxTime = examSubjects.get(i).getTimeLimits();
            //    }
            //    if(i != (examSubjects.size() - 1)){
            //        sb.append(examSubjects.get(i).getSubjectName()).append(",");
            //    }else{
            //        sb.append(examSubjects.get(i).getSubjectName());
            //    }
            //}
            map.put("maxTime",maxTime);
            map.put("subjectName",examSubjects.size());
        }
        return map;
    }

    public static Map<String,Object> examineeArrangeFirstOrDefault(List<Map<String,Object>> arrangeList,String examineeId){
        if(!arrangeList.isEmpty()){
            for (Map<String, Object> map:arrangeList){
                if(map.get("ExamineeID").equals(examineeId)){
                    return map;
                }
            }
        }
        return null;
    }

    public static List<ExamingMonitor> isDelayTime(List<ExamingMonitor> monitorList){
        List<ExamingMonitor> list = new ArrayList<>();
        if(!monitorList.isEmpty()){
            for (ExamingMonitor examingMonitor:monitorList) {
                if(examingMonitor.getDelayMinute() > 0){
                    list.add(examingMonitor);
                }
            }
        }
        return list;
    }

    public static ExamineeExamPaperItem getExamPaperItemById(List<ExamineeExamPaperItem> examPaperItemList, String itemId){
        return examPaperItemList.parallelStream().filter(paperItem -> itemId.toLowerCase().equals(paperItem.getItemID().toLowerCase())).findFirst().orElse(new ExamineeExamPaperItem());
    }

    /**
     * 获取当前用户信息
     * @param request
     * @return
     */
    public static AdminInfo getAdminInfo(HttpServletRequest request){
       return  (AdminInfo)request.getSession().getAttribute("Admin");
    }

    /**
     * 根据状态获取监控数据的数量
     * @param monitors
     * @return
     */
    public static Map<String,Object> getCountByStatus(List<ExamingMonitor> monitors){
        Map<String,Object> map = new HashMap<>();
        Integer examNotOpenCount = 0;
        Integer examOpenCount = 0;
        Integer examEndCount = 0;
        if(monitors != null && !monitors.isEmpty()){
            for (ExamingMonitor monitor:monitors) {
                Short sysState = monitor.getSysState();
                if(sysState.equals(ExamManagerState.Discipline.getPrefix().shortValue())){
                    examNotOpenCount++;
                }
                if(sysState.equals(ExamManagerState.Login.getPrefix().shortValue()) || sysState.equals(ExamManagerState.BeingNotSubmit.getPrefix().shortValue())){
                    examOpenCount++;
                }
                if(sysState.equals(ExamManagerState.Submited.getPrefix().shortValue())){
                    examEndCount++;
                }
            }
        }
        map.put("examNotOpenCount",examNotOpenCount);
        map.put("examOpenCount",examOpenCount);
        map.put("examEndCount",examEndCount);
        return map;
    }

    public static Map<String,Object> countFirstOrDefault(List<Map<String,Object>> absenceOrAllCountList,String subjectId,String appId){
        if(absenceOrAllCountList != null && !absenceOrAllCountList.isEmpty()){
            for (Map<String, Object> map:absenceOrAllCountList){
                if(subjectId != null && appId == null && (map.get("ExamSubjectID")).equals(subjectId)){
                    return map;
                }
                if(subjectId != null && appId != null && (map.get("ExamSubjectID")).equals(subjectId) && String.valueOf(map.get("AppID")).equals(appId)){
                    return map;
                }
            }
        }
        return null;
    }

    public static CompletionStatus getStatus(Integer prefix){
        CompletionStatus[] values = CompletionStatus.values();
        for (CompletionStatus value:values) {
            if(prefix.equals(value.getPrefix())){
                return value;
            }
        }
        return null;
    }

    public static ItemType getItemType(Integer prefix){
        ItemType[] values = ItemType.values();
        for (ItemType type:values) {
            if(prefix.equals(type.getIndex())){
                return type;
            }
        }
        return null;
    }

    public static Object getBehaviorByType(Integer type,String examinerID,String comment,String reason,String logTime,Integer delayedTime,String relBeginTime){
        switch (type){
            //延时
            case 1:
                DelayRecord delayRecord = new DelayRecord();
                delayRecord.setExaminerID(examinerID);
                delayRecord.setComment(comment);
                delayRecord.setOperationTime(logTime);
                delayRecord.setDelayDuration(delayedTime);
                return delayRecord;
            //换机
            case 2:
                ChangeSeatRecord changeSeatRecord = new ChangeSeatRecord();
                changeSeatRecord.setExaminerID(examinerID);
                changeSeatRecord.setComment(comment);
                changeSeatRecord.setOperationTime(logTime);
                return  changeSeatRecord;
            //强制交卷
            case 3:
                break;
            //作弊
            case 4:
                ViolateRuleRecord violateRuleRecord = new ViolateRuleRecord();
                violateRuleRecord.setExaminerID(examinerID);
                violateRuleRecord.setComment(comment);
                violateRuleRecord.setOperationTime(logTime);
                return violateRuleRecord;
            //调整时间
            case 5:
                ViolateRuleRecord violateRuleRecord2 = new ViolateRuleRecord();
                violateRuleRecord2.setExaminerID(examinerID);
                violateRuleRecord2.setComment(comment + reason);
                violateRuleRecord2.setOperationTime(logTime);
                return violateRuleRecord2;
            //整场重考
            case 6:
                AccidentsProcessRecord accidentsProcessing = new AccidentsProcessRecord();
                accidentsProcessing.setexamRoomID(examinerID);
                accidentsProcessing.setComment(comment);
                accidentsProcessing.setOperationTime(relBeginTime);
                return accidentsProcessing;
            default:
                break;
        }
        return null;
    }

    /**
     * Double 做除法
     * @param d1
     * @param d2
     * @return
     */
    public static Double getDoubleDiv(Double d1,Double d2){
        //b1/b2
        BigDecimal b1 = new BigDecimal(Double.toString(d1));
        BigDecimal b2 = new BigDecimal(Double.toString(d2));
        return b1.divide(b2, 2, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 验证考试计划信息
     * @param examPlan
     * @return
     */
    public static String checkExamPlan(ExamPlan examPlan){
        String progressInfo = null;
        if(examPlan == null){
            progressInfo = "该计划包信息为空！";
        }else if(!CheckPackage.getInstances().validateExamExamineeNum(examPlan)){
            progressInfo = "考生数量小于等于0！";
        }else if(!CheckPackage.getInstances().validateExamRoomsNum(examPlan)){
            progressInfo = "考场数量小于等于0！";
        }
        return progressInfo;
    }

    /**
     * 判断当前题型是否是主观题
     * @param itemType
     * @return
     */
    public static Boolean isSubjective(Integer itemType){
        List<Integer> subjectiveItemType = Arrays.asList(ItemType.TEXTENTRY.getIndex(), ItemType.EXTENDEDTEXT.getIndex(), ItemType.UPLOAD.getIndex(), ItemType.COMPOSITE.getIndex());
        return subjectiveItemType.contains(itemType);
    }

    public static void notifyManager(String baseUrl,String apiUrl,String message,String... phones){
        HashMap<String, Object> parameterMap = new HashMap<>(8);
        HashMap<String, String> headers = new HashMap<>(3);
        headers.put("Content-Type","application/json");
        headers.put("appKey","61ffe3db1e0711e98e21005056903273");
        parameterMap.put("deviceInfo","notify");
        parameterMap.put("referCust","1");
        parameterMap.put("content",message);
        parameterMap.put("accountLogin","");
        parameterMap.put("ipAddress","notify");
        parameterMap.put("appSceneType","5");
        parameterMap.put("credentialNO","110010110");
        for (String phone : phones) {
            parameterMap.put("mobiles",phone);
            HttpRequestUtils.send_UnirestRecoredSaving_post(baseUrl,apiUrl,parameterMap,headers);
        }

    }
}
